# coding: utf-8
from typing import Union, List, Literal
from PyQt6.QtCore import QThreadPool
from PIL import Image
from PyQt6.QtWidgets import QApplication
from svglib.svglib import svg2rlg
from reportlab.graphics import renderSVG, renderPM, renderPS, renderPDF
from pathlib import Path

SVGFormat = Literal['png', 'pdf', 'ps', 'svg', 'gif']
PILFormat = Literal['PNG', 'GIF', 'JPEG', 'BMP', 'TIFF', 'PCX', 'PPM', 'PBM', 'PGM', 'EPS', 'IM', 'FITS']


class SVGConverter:
    """
    This class is used to convert SVG files to other formats.
    """

    def __init__(
            self,
            file: Union[str, Path],
            save_to: str,
            output_width: int = None,
            output_height: int = None,
            bg: str = None,
            dpi: int = 96,
            scale: float = 1
    ):
        self.svg_pic = svg2rlg(file)
        self.svg_pic.height = output_height or self.svg_pic.height
        self.svg_pic.width = output_width or self.svg_pic.width
        self.svg_pic.scale(scale)
        self.params = {
            'fn': save_to,
            'bg': bg or 0xffffff,
            'dpi': dpi
        }

    def toPNG(self):
        return renderPM.save(self.svg_pic, fmt='PNG', **self.params)

    def toGIF(self):
        return renderPM.save(self.svg_pic, fmt='GIF', **self.params)

    def toPDF(self):
        return renderPDF.drawToFile(self.svg_pic, self.params['fn'])

    def toPS(self):
        return renderPS.drawToFile(self.svg_pic, self.params['fn'])

    def toSVG(self):
        return renderSVG.drawToFile(self.svg_pic, self.params['fn'])

    @staticmethod
    def convert(
            file: str,
            save_to: str,
            output_width: int = None,
            output_height: int = None,
            bg: str = 0xffffff,
            dpi: int = 96,
            scale: float = 1,
            format: SVGFormat = 'png'
    ):
        svg_obj = SVGConverter(
            file, save_to,
            output_width, output_height,
            bg, dpi, scale
        )
        if format == 'png':
            svg_obj.toPNG()
        elif format == 'pdf':
            svg_obj.toPDF()
        elif format == 'ps':
            svg_obj.toPS()
        elif format == 'svg':
            svg_obj.toSVG()
        elif format == 'gif':
            svg_obj.toGIF()
        else:
            raise ValueError('Invalid format')

    @staticmethod
    def pool_convert(
            files: Union[str, List[str]],
            save_path: Union[str, Path],
            output_width: int = None,
            output_height: int = None,
            bg: str = 0xffffff,
            dpi: int = 96,
            scale: float = 1,
            format: SVGFormat = 'png'
    ):
        if isinstance(save_path, str):
            save_path = Path(save_path)

        pool = QThreadPool()
        pool.setMaxThreadCount(6)
        if isinstance(files, str):
            files = [files]
        for file in files:
            file = Path(file)
            save_to = (save_path / (file.stem + '.' + format)).as_posix()
            pool.start(lambda f=file, sv=save_to: SVGConverter.convert(
                f, sv,
                output_width, output_height,
                bg, dpi, scale, format
            ))
        pool.waitForDone()


class ImageConverter:
    @staticmethod
    def convert(
            file: str,
            save_to: str,
            format: PILFormat = 'PNG'
    ):
        img = Image.open(file)
        if img.mode == 'RGB':
            img = img.convert('RGBA')

        img.save(save_to, format=format)

    @staticmethod
    def pool_convert(
            files: Union[str, List[str]],
            save_path: Union[str, Path],
            format: PILFormat = 'PNG'
    ):
        if isinstance(save_path, str):
            save_path = Path(save_path)

        pool = QThreadPool()
        pool.setMaxThreadCount(6)
        if isinstance(files, str):
            files = [files]
        for file in files:
            file = Path(file)
            save_to = (save_path / (file.stem + '.' + format.lower())).as_posix()
            pool.start(lambda: ImageConverter.convert(
                file, save_to, format
            ))


if __name__ == '__main__':
    app = QApplication([])
    SVGConverter.pool_convert(
        [
            r'F:\PythonObject\python-tools-box\resources\images\icons\Batch_black.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\Batch_white.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\DataBase_black.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\DataBase_white.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\EmojiTabSymbols_black.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\EmojiTabSymbols_white.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\Excel_black.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\Excel_white.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\Fps_black.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\Fps_white.svg',
            r'F:\PythonObject\python-tools-box\resources\images\icons\Grid_black.svg'
        ],
        r'C:\Users\26406\Downloads',
        bg='#dfe4ea',
    )
    app.exec()
